﻿namespace NJQuery {
	using System.ComponentModel;
	using System.Diagnostics.CodeAnalysis;

	/// <summary>
	/// Uses <see cref="ManagedControl" /> to provide a standard base implementation of the <see cref="IEffect" /> contract needed by the jQuery UI server controls render effect definitions to the client.
	/// </summary>
	public abstract class EffectBase : ManagedControl, IEffect {


		#region Constants: Property defaults

		private const string defaultSpeedString = "Normal";

		#endregion


		#region Static Readonly Fields: Property defaults

		private static readonly Duration defaultSpeed = Duration.Normal;

		#endregion


		#region Fields

		private string effect;

		#endregion


		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="EffectBase" /> class.
		/// </summary>
		/// <param name="effect">The name of the jQuery UI effect used by the client.</param>
		protected EffectBase(string effect) {
			this.effect = effect;
		}

		#endregion


		#region Properties

		/// <summary>
		/// Gets the name of the jQuery UI effect.
		/// </summary>
		public virtual string Effect {
			get { return effect; }
		}

		/// <summary>
		/// Gets or sets the duration/speed of the jQuery UI effect.
		/// </summary>
		[DefaultValue(typeof(Duration), defaultSpeedString), Category("Behavior")]
		public virtual Duration Speed {
			get { return ViewState["Speed"] as Duration? ?? defaultSpeed; }
			set { ViewState["Speed"] = value; }
		}

		#endregion


		#region Methods: Rendering hooks

		/// <summary>
		/// Allows a jQuery server control to reference scripts and stylesheets necessary to render their client markup and widgets.
		/// </summary>
		/// <param name="manager">The <see cref="Manager"/> used to handle style and script referencing in addition to unified generation of load and ready scripts.</param>
		protected override void Register(Manager manager) {
			manager.RegisterClientScript(ClientScript.Core);
			//manager.RegisterClientScript(ClientScript.UICore);
			manager.RegisterClientScript(ClientScript.UIEffectsCore);
		}

		/// <summary>
		/// Creates the properties object that will be rendered as the jQuery UI initialization options.
		/// This method is used primarily by control developers.
		/// </summary>
		/// <returns>A <see cref="PropertyCollection"/> object that will become the jQuery UI initialization options.</returns>
		protected virtual PropertyCollection CreateProperties() {
			PropertyCollection properties = new PropertyCollection();

			properties.AddValue("effect", Effect);
			properties.AddValue("options", CreateOptionProperties());
			properties.AddValue("speed", Speed);

			return properties;
		}

		/// <summary>
		/// Returns a <see cref="PropertyCollection"/> containing option values specific to the effect.
		/// This method is used primarily by control developers.
		/// </summary>
		/// <returns>A <see cref="PropertyCollection"/> containing the effect's option values.</returns>
		protected virtual PropertyCollection CreateOptionProperties() {
			return new PropertyCollection();
		}

		#endregion


		#region Explicit Implementation: IEffect


		[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "It's called ID for any derivatives.")]
		string IEffect.ControlId {
			get { return ID; }
		}

		PropertyCollection IEffect.CreateProperties() {
			return CreateProperties();
		}

		PropertyCollection IEffect.CreateOptionProperties() {
			return CreateOptionProperties();
		}

		#endregion


	}

}